package com.caihao.docdemo.util;

import lombok.extern.slf4j.Slf4j;

import java.io.*;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;

/**
 * create by caihao on 2021/4/1
 */
@Slf4j
public class WordUtil {
    /**
     * docx模板替换。outputStream 输出流可以自己定义 浏览器或者文件输出流。
     * 注意：outputstream没有close
     *
     * @param sourcePath docx文件所在目录
     * @param dataMap 模板替换的值
     * @param fileName xxx.docx
     * @param outputStream 输出流
     * @return void
     * @date 2021/4/6 14:22
     * @since 1.0.0
     */
    @SuppressWarnings("Duplicates")
    public static void createDocx(String sourcePath, Map dataMap, String fileName,OutputStream outputStream) {
        ZipOutputStream zipout = null;
        try {
            //图片配置文件模板
            ByteArrayInputStream documentXmlRelsInput = FreeMarkUtil.getFreemarkerContentInputStream(sourcePath, dataMap,
                    "document.xml.rels");
            //内容模板
            ByteArrayInputStream documentInput = FreeMarkUtil.getFreemarkerContentInputStream(sourcePath, dataMap, "document.xml");
            //最初设计的模板
            File docxFile =
                    new File(sourcePath,fileName);
            if (!docxFile.exists()) {
                docxFile.createNewFile();
            }
            ZipFile zipFile = new ZipFile(docxFile);
            Enumeration<? extends ZipEntry> zipEntrys = zipFile.entries();
            zipout = new ZipOutputStream(outputStream);
            //开始覆盖文档------------------
            int len = -1;
            byte[] buffer = new byte[1024];
            while (zipEntrys.hasMoreElements()) {
                ZipEntry next = zipEntrys.nextElement();
                InputStream is = zipFile.getInputStream(next);
                if (next.toString().indexOf("media") < 0) {
                    zipout.putNextEntry(new ZipEntry(next.getName()));
                    if (next.getName().indexOf("document.xml.rels") > 0) { //如果是document.xml.rels由我们输入
                        if (documentXmlRelsInput != null) {
                            while ((len = documentXmlRelsInput.read(buffer)) != -1) {
                                zipout.write(buffer, 0, len);
                            }
                            documentXmlRelsInput.close();
                        }
                    } else if ("word/document.xml".equals(next.getName())) {//如果是word/document.xml由我们输入
                        if (documentInput != null) {
                            while ((len = documentInput.read(buffer)) != -1) {
                                zipout.write(buffer, 0, len);
                            }
                            documentInput.close();
                        }
                    } else {
                        while ((len = is.read(buffer)) != -1) {
                            zipout.write(buffer, 0, len);
                        }
                        is.close();
                    }
                }
            }
            //写入图片
            List<Map<String, Object>> picList = (List<Map<String, Object>>) dataMap.get("picList");
            if (picList != null && picList.size() > 0) {
                for (Map<String, Object> pic : picList) {
                    ZipEntry next = new ZipEntry("word" + "-" + "media" + "-" + pic.get("name"));
                    zipout.putNextEntry(new ZipEntry(next.toString()));
                    InputStream in = (ByteArrayInputStream) pic.get("code");
                    while ((len = in.read(buffer)) != -1) {
                        zipout.write(buffer, 0, len);
                    }
                    in.close();
                }
            }
        } catch (Exception e) {
            log.error("word导出失败:" + e.getStackTrace());
            e.printStackTrace();
        } finally {
            if (zipout != null) {
                try {
                    zipout.close();
                } catch (IOException e) {
                    log.error("io异常");
                    e.printStackTrace();
                }
            }
//            if (outputStream != null) {
//                try {
//                    outputStream.close();
//                } catch (IOException e) {
//                    log.error("io异常");
//                    e.printStackTrace();
//                }
//            }
        }
    }

}
